(function($) {

	$.exporter = $.exporter || {};

	$.extend($.exporter, {
		extend : function(methods) {
			$.fn.extend(methods);
		}
	});

	$.fn.exporter = function(option) {

		option = $.extend(true, {
			url : jsContextPath + '/export/toExcel.do',// 导出的url
			postData : {},
			filename : null,// 文件名称
			modelHandler : getModel,
			hideCols : false,
			filenameGenerate : getFileName,
			/**
			 * formats示例： key：是字段名称 value:formatoption formatoption:
			 * decimal:保留多少位小数 align：对齐方式
			 * suffix:后缀（对度量值有效）,cellSpan:是否要合并单元格，true:是，false：否
			 * valueTable:值转换的表，key:原值，value:目标值 eg: { 'PERCETNT':{ decimal:2
			 * align:'right', suffix:'%',valueMap:{}, hidden:是否隐藏列 } }
			 */
			formats : {},
			template : {
				enable : false,
				file : ''
			}
		}, option || {});

		var modelHandler = option.modelHandler;

		this.each(function() {
			var self = this, $self = $(self);
			// 该元素添加click事件
				$(self)
						.click(function() {
							// 拼接参数
								var filename = option.filename;
								// 取默认的文件名
								if (!filename) {

									if ($.isFunction(option.filenameGenerate)) {
										filename = option
												.filenameGenerate($self);
									}

									if (!filename) {
										alert('请配置文件名');
										return;
									}
								}

								var subTitle = $self.attr('subTitle');
								if (subTitle) {
									filename += '—' + subTitle;
								}

								var postData = option.postData;
								var models = modelHandler($self, option.formats);

								for ( var i in models) {
									var model = models[i];
									var grid = model.grid;
									if (grid) {
										delete model.grid;
										modelProcess(option, model);
										var postData_ = $.extend(true, {},
												postData);
										postData_ = $.extend(true, postData_,
												$(grid)
														.getGridParam(
																'postData'));

										postData_.filename = filename;
										delete postData_.grid;
										for ( var k in model) {
											postData_[k] = model[k];
										}

										var template = option.template;
										postData_.isTempl = template.enable;
										postData_.file = template.file;

										var dataStr = $.utils
												.obj2str(postData_);
										var url = option.url;

										var expForm = $('<form id="doExport" action="' + url + '"method="post" target="_blank"></form>');
										$('body').append(expForm);

										var arr = dataStr.split('&');
										for ( var a in arr) {
											var param = arr[a].split('=');
											if (param.length > 0) {
												var name = param[0], value = param.length > 1 ? param[1]
														: '';
												expForm
														.append('<input type="hidden" name="'
																+ name
																+ '" value="'
																+ value + '"/>');
											}

										}

										expForm[0].submit();
										expForm.remove();
									}
								}

							});

			});

	};

	/**
	 * 默认获取图表数据
	 */
	function getModel(obj, formats) {

		var models = [];

		var target = $(obj).attr('grids');
		var grids = target.split(';');

		for ( var g in grids) {
			var expModel = {
				headerGroup : [],
				cells : [],
				grid : null
			};

			var $grid = $('#' + grids[g]), grid = $grid[0];
			var colNames = grid.p.colNames, colModel = grid.p.colModel;

			// 单元格属性
			var cells = [];

			var formats_ = $.extend(true, {}, formats);
			// 设置单元格属性
			for ( var i = 0; i < colModel.length; i++) {
				var cm = colModel[i];
				if (!cm.hidedlg && !cm.hidden) {
					var attr = getCellAttr(cm);

					if (formats_[cm.name]) {// formats有值，将formats值放入属性里面
						var format = formats_[cm.name];

						var valueTable = format.valueTable || {}, tableStr = '';
						for ( var k in valueTable) {
							tableStr += k + ':' + valueTable[k] + ';';
						}
						format.valueTable = tableStr;
						attr = $.extend(true, attr, format);
					}

					cells.push(attr);
				}
			}

			// 标题
			var headerGroup = [], headers = [];

			// 设置标题
			var uiGrid = $(grid).parents('div.ui-jqgrid');
			var headTable = uiGrid.find('table.ui-jqgrid-htable'), tr = headTable
					.find('tr');

			for ( var j = 0; j < tr.length; j++) {
				var $tr = $(tr[j]);
				// 排除aria-hidden为true的行
				if ('true' == $tr.attr('aria-hidden')) {
					continue;
				}

				var ths = $tr.find('th');
				var headers = [];
				for ( var k = 0; k < ths.length; k++) {
					var $th = $(ths[k]);
					var display = $th.css('display');
					// 排除jqGrid序号和隐藏的列
					if (grid.id + '_rn' != $th.attr('id') && 'none' != display) {
						var colspan = $th.attr('colspan') || 1, rowspan = $th
								.attr('rowspan') || 1;
						headers.push( {
							name : $th.text(),
							colSpan : parseInt(colspan),
							rowSpan : parseInt(rowspan)
						})
					}
				}

				headerGroup.push( {
					headers : headers
				});
			}

			expModel.headerGroup = headerGroup;

			expModel.cells = cells;
			expModel.grid = grid;

			models.push(expModel);
		}

		return models;
	}
	;

	/**
	 * 获取单元格的格式
	 * 
	 * @param colModel
	 * @return
	 */
	function getCellAttr(colModel) {
		var attr = {
			code : colModel.name,
			align : colModel.align,
			cellSpan : colModel.cellSpan
		};

		var formatoptions = colModel.formatoptions;
		if (formatoptions) {
			if (formatoptions.decimalPlaces) {
				attr.decimal = formatoptions.decimalPlaces;
			}
			attr.suffix = formatoptions.suffix;
		}
		return attr;
	}
	;

	/**
	 * 默认获取文件名
	 * 
	 * @param obj
	 * @return
	 */
	function getFileName(obj) {

		var head = obj.parents('div.panel-head');
		var h = head.find('h2');
		return h.text() ? $.trim(h.text()) : '';
	}
	;

	/**
	 * 处理model对象
	 */
	function modelProcess(option, model) {
		if (option.hideCols) {
			hideCols(model)
		}
	}
	;

	/**
	 * 隐藏列
	 */
	function hideCols(model) {
		var headerGroup = model.headerGroup;
		var cells = model.cells;

		var a1 = getHeadArray(headerGroup, cells);

		for ( var i = 0; i < headerGroup.length; i++) {
			var headers = headerGroup[i].headers;
			var current = a1[i];
			var pos = 0;
			for ( var h = 0; h < headers.length; h++) {

				for ( var a = pos; a < current.length; a++) {
					if (current[a] == null) {
						var rowSpan = headers[h].rowSpan, colSpan = headers[h].colSpan;
						pos += colSpan;
						for ( var r = i; r < rowSpan + i; r++) {
							var array = a1[r];
							for ( var c = a; c < colSpan + a; c++) {
								array[c] = headers[h];
								headers[h].start = a;
								headers[h].row = i;
								headers[h].column = h;
							}
						}

						break;
					}
				}
			}
		}

		delHead(headerGroup, cells, a1);
	}
	;

	function getHeadArray(headerGroup, cells) {
		var a1 = [];
		for ( var i = 0; i < headerGroup.length; i++) {
			var a2 = [];
			for ( var j = 0; j < cells.length; j++) {
				a2.push(null);
			}

			a1.push(a2);
		}
		return a1;
	}
	;

	/**
	 * 删除单元格
	 */
	function delHead(headerGroup, cells, array) {
		for ( var i = 0; i < cells.length; i++) {
			var cell = cells[i];
			if (cell.hidden) {
				for ( var j = 0; j < array.length; j++) {
					// 获取二维数组
					var a = array[j];
					// 获取单元格
					var target = a[i];

					var row = target.row, column = target.column;
					if (j == row) {
						var headers = headerGroup[j].headers;
						var header = headers[column];
						if (header != null) {
							var colSpan = header.colSpan;
							if (colSpan > 1) {
								header.colSpan = colSpan - 1;
							} else {
								headers[column] = null;
							}
						}

					}
				}

				cells[i] = null;

			}
		}

		for ( var s = 0; s < headerGroup.length; s++) {
			var hs = headerGroup[s].headers;
			for ( var k = 0; k < hs.length; k++) {
				var head = hs[k];
				if (!head) {
					hs.splice(k, 1);
				}
			}
		}

		for ( var c in cells) {
			if (!cells[c]) {
				cells.splice(c, 1);
			}
		}

	}
	;

})(jQuery);